package djboom.materials.display.elements {
	import com.greensock.TweenLite;
	import com.greensock.easing.Strong;

	import org.casalib.display.CasaSprite;
	import org.casalib.util.StageReference;

	import flash.display.DisplayObject;
	import flash.display.Shape;
	import flash.display.Sprite;
	import flash.events.EventPhase;
	import flash.events.MouseEvent;
	import flash.events.TimerEvent;
	import flash.geom.Rectangle;
	import flash.utils.Timer;

	/**
	 * Скроллинг.
	 * <br>
	 * 
	 * @author DJ BooM 
	 * @since 24.09.2009
	 * 
	 */

	public class Scroll extends CasaSprite {

		// ----------------------------------------------------------------------------
		// Свойства класса.
		// ----------------------------------------------------------------------------

		private var _visibleHeight:int;
		
		private var _clicked:DisplayObject;
		private var _timer:Timer;
		
		private var _spriteRectangle:Rectangle;
		private var _scrollSprite:DisplayObject;

		private var _BARPOS_Y_MIN:int;		private var _BARPOS_Y_MAX:int;

		private var _scrollSpriteHeight:int;

		private var _scrollBar:Sprite;
		private var _scrollHeight:int;
		private var _deltaHeight:int;

		private static const SPEED_SCROLL:int = 10;
		private var _diamond:Diamond;

		// ----------------------------------------------------------------------------
		// Конструктор.
		// ----------------------------------------------------------------------------

		public function Scroll(scrollSprite:DisplayObject, visibleHeight:int, scrollHeight:int) {
			_scrollSprite = scrollSprite;			
			_visibleHeight = visibleHeight;
			_scrollHeight = scrollHeight;
			
			_deltaHeight = _scrollSprite.height - _visibleHeight;

			_scrollSpriteHeight = _scrollSprite.height;
			
			var backgroundBlack:Shape = new Shape();
			backgroundBlack.graphics.beginFill(0x25bed2);			
			backgroundBlack.graphics.drawRect(8, 0, 2, _scrollHeight);
			backgroundBlack.graphics.endFill();			
			addChild(backgroundBlack);
			
			_scrollBar = new Sprite();
			_scrollBar.buttonMode = true;
			_scrollBar.useHandCursor = true;
			addChild(_scrollBar);
			
			_diamond = new Diamond(Diamond.GREEN);
			_scrollBar.addChild(_diamond);
			
			_spriteRectangle = new Rectangle(0, 0, _scrollSprite.width, _visibleHeight);
			_scrollSprite.scrollRect = _spriteRectangle;

			_BARPOS_Y_MIN = 0;
			_BARPOS_Y_MAX = scrollHeight - 17;
			
			_scrollBar.addEventListener(MouseEvent.MOUSE_DOWN, dragBar);			_scrollBar.addEventListener(MouseEvent.MOUSE_UP, stopDragBar);

			StageReference.getStage().addEventListener(MouseEvent.MOUSE_UP, captureMouseUp);
			StageReference.getStage().addEventListener(MouseEvent.MOUSE_UP, captureMouseUp, true);

			scrollSprite.addEventListener(MouseEvent.MOUSE_WHEEL, scrollMouse);
		}

		// ----------------------------------------------------------------------------
		// Приватные методы.
		// ----------------------------------------------------------------------------
		
		private function scrollMouse(event:MouseEvent):void {
			var newX:int = _scrollBar.y - event.delta * SPEED_SCROLL;
			
			if (newX > _BARPOS_Y_MIN && newX < _BARPOS_Y_MAX) {
				_scrollBar.y = newX;
			} else {
				if (newX > _BARPOS_Y_MAX) {
					_scrollBar.y = _BARPOS_Y_MAX;
				}
				
				if (newX < _BARPOS_Y_MIN) {
					_scrollBar.y = _BARPOS_Y_MIN;
				} 
			}
			
			refreshScrollContent();
		}

		private function captureMouseUp(event:MouseEvent):void {
			if (event.eventPhase == EventPhase.BUBBLING_PHASE) return;
    
			if (_clicked == _scrollBar) {
				_clicked = null;

				var target:Sprite = event.target as Sprite;

				if (target == _scrollBar) {
					stopDragBar(event);
				} else {
					stopDragBar(event);
				}
			}
		}

		private function dragBar(event:MouseEvent):void {
			_clicked = _scrollBar;
			_scrollBar.startDrag(false, new Rectangle(0, 0, 0, _BARPOS_Y_MAX - _BARPOS_Y_MIN));
			
			_timer = new Timer(30);
			_timer.addEventListener(TimerEvent.TIMER, checkContentScroll);
			_timer.start();
		}

		private function checkContentScroll(event:TimerEvent):void {
			refreshScrollContent();
		}

		private function stopDragBar(event:MouseEvent):void {
			_scrollBar.stopDrag();
			_timer.stop();
			
			refreshScrollContent();
		}

		private function refreshScrollContent():void {
			var currentY:int = ((_scrollBar.y) * (_scrollSpriteHeight - _visibleHeight)) / (_BARPOS_Y_MAX - _BARPOS_Y_MIN);
			
			TweenLite.to(_scrollSprite, 0.4, {scrollRect: {y: currentY}, ease: Strong.easeOut, overwrite: 1});
		}
	}
}